import initSqlJs, { Database } from "sql.js"

// 单例模式保持数据库连接
let db: Database | null = null;
let initPromise: Promise<void> | null = null;

// 初始化SQL.js
export async function initDatabase() {
  if (initPromise) return initPromise;

  initPromise = new Promise(async (resolve, reject) => {
    try {
      // 确保仅在浏览器环境中运行
      if (typeof window === 'undefined') {
        throw new Error('SQL.js 仅支持在浏览器环境中运行');
      }

      // 添加提示信息
      console.log('开始初始化 SQL.js...');

      // 动态导入SQL.js
      const SQL = await initSqlJs({
        // 指定wasm文件位置
        locateFile: (file: string) => `https://sql.js.org/dist/${file}`
      });

      // 创建新的数据库实例
      db = new SQL.Database();
      console.log("SQL.js数据库初始化成功");
      resolve();
    } catch (error) {
      console.error("SQL.js数据库初始化失败:", error);
      reject(error);
    }
  });

  return initPromise;
}

// 执行SQL查询
export async function executeQuery(query: string) {
  if (!db) {
    console.log('数据库尚未初始化，现在初始化...');
    await initDatabase();
    if (!db) {
      throw new Error('数据库初始化失败');
    }
  }

  try {
    console.log('执行查询:', query.substring(0, 50) + (query.length > 50 ? '...' : ''));

    // 执行查询
    const results = db!.exec(query);

    if (results.length === 0) {
      // 如果没有结果集，可能是INSERT/UPDATE/DELETE操作
      const rowsAffected = db!.getRowsModified();
      console.log(`查询执行成功，影响了 ${rowsAffected} 行`);
      return {
        columns: [],
        rows: [],
        // 返回受影响的行数
        rowsAffected
      };
    }

    // 处理查询结果
    const columns = results[0].columns;
    const rows = results[0].values.map((row: any[]) => {
      const rowObj: Record<string, any> = {};
      columns.forEach((col: string, i: number) => {
        rowObj[col] = row[i];
      });
      return rowObj;
    });

    console.log(`查询执行成功，返回 ${rows.length} 行结果`);
    return { columns, rows, rowsAffected: 0 };
  } catch (error) {
    // 详细记录错误
    console.error("查询执行失败:", error);
    const errorMessage = String(error);

    // 对常见错误提供更友好的错误消息
    if (errorMessage.includes('no such table')) {
      throw new Error(`表不存在: ${errorMessage}`);
    } else if (errorMessage.includes('syntax error')) {
      throw new Error(`SQL语法错误: ${errorMessage}`);
    } else if (errorMessage.includes('UNIQUE constraint failed')) {
      throw new Error(`违反唯一约束: ${errorMessage}`);
    } else {
      throw error;
    }
  }
}

// 重置数据库
export async function resetDatabase() {
  try {
    console.log('开始重置数据库...');

    if (!db) {
      console.log('数据库尚未初始化，将进行初始化...');
      await initDatabase();
    } else {
      console.log('数据库已初始化，将清空现有数据...');

      // 先尝试删除已知的表
      try {
        // 获取外键状态并暂时禁用外键约束
        const fkEnabled = db.exec("PRAGMA foreign_keys;");
        db.exec("PRAGMA foreign_keys = OFF;");

        // 查询所有表名
        const tables = db.exec("SELECT name FROM sqlite_master WHERE type='table'");

        if (tables.length > 0 && tables[0].values.length > 0) {
          console.log('找到以下表，将会删除:', tables[0].values.join(', '));

          // 针对每个表执行 DROP TABLE
          for (const [tableName] of tables[0].values) {
            // 跳过 sqlite_ 开头的系统表
            if (!String(tableName).startsWith('sqlite_')) {
              console.log(`删除表: ${tableName}`);
              db.exec(`DROP TABLE IF EXISTS "${tableName}"`);
            }
          }
        } else {
          console.log('没有找到要删除的表');
        }

        // 恢复外键约束状态
        if (fkEnabled.length > 0 && fkEnabled[0].values.length > 0) {
          const status = fkEnabled[0].values[0][0];
          db.exec(`PRAGMA foreign_keys = ${status};`);
        }
      } catch (dropError) {
        console.warn("删除表时出错，将重新创建数据库:", dropError);
      }

      // 关闭旧数据库连接并创建新的数据库
      console.log('关闭旧数据库连接，创建新数据库...');
      db.close();
      const SQL = await initSqlJs({
        locateFile: (file: string) => `https://sql.js.org/dist/${file}`
      });
      db = new SQL.Database();
      console.log("数据库已成功重置，创建了一个全新的实例");
    }
    return { success: true };
  } catch (error) {
    console.error("重置数据库失败:", error);
    throw error;
  }
}

// 导出数据库为二进制数据
export function exportDatabase() {
  if (!db) return null;
  return db.export();
}

// 从二进制数据导入数据库
export async function importDatabase(data: Uint8Array) {
  const SQL = await initSqlJs({
    locateFile: (file: any) => `https://sql.js.org/dist/${file}`
  });

  if (db) {
    db.close();
  }

  db = new SQL.Database(data);
  return { success: true };
}

